//
//  queueTool.h
//  operation_system_experiment_1
//
//  the tools for the experiment.
//
//  Created by MAC on 2017/11/13.
//  Copyright © 2017年 blackay(5322). All rights reserved.
//


typedef struct Job {                            //任务结构体
     int  jobnum; 	                            //任务号
     int  arrivetime;                           //到达时间
     int  burst;	                            //运行时间
	 int  leavetime;                            //离开时间
	 int  roundtime;                            //周转时间
	 int  runtime;                              //已运行时间
}ElemType;

//typedef struct Job ElemType;
typedef struct LNode{                           //反馈队列结构体，存储任务值和下一个成员的指针
	ElemType data;
	struct LNode* next;
}LNode;

typedef struct LinkQueue{                       //大队列结构体，将三个队列串起来
	LNode* front;      //首
	LNode* rear;       //尾
    //struct LinkQueue* Qfront;
    //struct LinkQueue* Qrear;
}LinkQueue;

void InitQueue(LinkQueue *jobqueue, int i)            //初始化队列，指针必需初始化
{
	jobqueue->rear = NULL;
    jobqueue->front = NULL;
    //HQ->Qfront = NULL;
    //HQ->Qrear = NULL;

}

void EnQueue(LinkQueue *jobqueue,ElemType job)  //入队函数
{
    LNode* newptr = (LNode *)malloc(sizeof(LNode));
    newptr->data = job;
    newptr->next = NULL;
    if (jobqueue->rear == NULL){
        jobqueue->front = jobqueue->rear = newptr;
        //jobqueue->front->next = NULL;
    }
    //else if(jobqueue->rear->data.arrivetime==0)
    //    jobqueue->front = jobqueue->rear = newptr;
    else
        jobqueue->rear = jobqueue->rear->next = newptr;
    //return jobqueue;
    //jobqueue->rear->next=NULL;
    
}

ElemType OutQueue(LinkQueue *jobqueue)      //出队函数
{
    
    ElemType temp=jobqueue->front->data;    //记住信息
    LNode* p = (LNode *)malloc(sizeof(LNode));
    p = jobqueue->front;
    
    jobqueue->front=p->next;                //队首指向一个临时linkqueue
    //p->next = jobqueue->front;
    if (jobqueue->front == NULL)
        jobqueue->rear = NULL;
    /*
    if(jobqueue->rear == p)
        jobqueue->rear = jobqueue->front;
    
    if(jobqueue->front->next!=NULL)
        jobqueue->front = jobqueue->front->next;
     */
    free(p = NULL);                           //出队
    return temp;
}

ElemType *PeekQueue(LinkQueue *jobqueue)            //取队列队首结构体的值
{
    if (jobqueue->front == NULL) {
        printf("队列为空无首元素。\n" );
        exit(1);
    }
    return &jobqueue->front->data;
}

int EmptyQueue(LinkQueue *jobqueue)               //判断队列是否为空（0），不空（1）
{
    if(jobqueue->front == NULL) return 0;
    else return 1;
}

void ClearQueue(LinkQueue *jobqueue)              //清空队列
{
    LNode *p = jobqueue->front;
    while(p != NULL) {
        jobqueue->front=jobqueue->front->next;
        free(p = NULL);
        p = jobqueue->front;
    }
    jobqueue->rear = NULL;
}

void function(LinkQueue *jobqueue, int timing)  //运行
{
  int leatime[3];                               //时间片的大小，三种长度
  leatime[0]=1;
  leatime[1]=2;
  leatime[2]=3;
  
  struct Job *t=NULL;
  int i=0;                                      //队列标号
  while(i<3)
  {
	  if(EmptyQueue(&jobqueue[i])==1)           //如果队列不为空
	  {
          //jobqueue[i].rear->next = NULL;
            t=PeekQueue(&jobqueue[i]);          //读取队首元素
		    t->runtime++;                       //已运行时间+1
		    if(t->runtime == t->burst)          //如果已经运行完毕，计算周转时间
			{
				t->leavetime=timing+1;
                t->roundtime =t->leavetime - t->arrivetime;
                printf("num:%d leave:%d run:%d round(leave-arrive):%d\n",t->jobnum,t->leavetime,t->runtime,t->roundtime);
	            
				OutQueue(&jobqueue[i]);         //这里运行完毕，出队
			}
          
            else if((t->runtime == leatime[i]) && (i<=2))           //如果在时间片内没有运行完，调整优先级，进入另一个队列
                EnQueue(&jobqueue[i+1],OutQueue(&jobqueue[i]));     //这里先记录结构体的值，然后在另一个队列中新建一个任务传值
			
            //printf("调试点4完毕\n");
            break;
	  }
	  i++;                                                          //队列为空，就进入下一个队列查看
  }
}

void create(LinkQueue* jobqueue,ElemType job)                       //在队列中插入任务
{
    job.runtime=0;
    EnQueue(&jobqueue[0],job);
}
